FreeRTOS 系统
ESP32 FreeRTOS 是一个实时操作系统内核,专门为 ESP32 微控制器优化。它允许你创建多个任务(tasks)来并行执行不同的功能,提供任务调度、内存管理、任务间通信等功能。
主要特点:
- 多任务处理:同时运行多个任务
- 任务优先级:不同任务可以有不同的执行优先级
- 任务间通信:队列、信号量、互斥锁等
- 内存管理:动态内存分配
- 定时器:软件定时器功能
代码示例
1. 基础多任务示例
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
static const char *TAG = "MULTITASK";
// 任务1:LED闪烁
void led_task(void *parameter) {
int led_pin = 2; // ESP32内置LED
gpio_set_direction((gpio_num_t)led_pin, GPIO_MODE_OUTPUT);
while (1) {
gpio_set_level((gpio_num_t)led_pin, 1); // 点亮LED
ESP_LOGI(TAG, "LED ON");
vTaskDelay(pdMS_TO_TICKS(1000)); // 延时1秒
gpio_set_level((gpio_num_t)led_pin, 0); // 熄灭LED
ESP_LOGI(TAG, "LED OFF");
vTaskDelay(pdMS_TO_TICKS(1000)); // 延时1秒
}
}
// 任务2:传感器读取
void sensor_task(void *parameter) {
int counter = 0;
while (1) {
// 模拟读取传感器数据
float temperature = 25.5 + (counter % 10);
ESP_LOGI(TAG, "Temperature: %.1f°C", temperature);
counter++;
vTaskDelay(pdMS_TO_TICKS(2000)); // 延时2秒
}
}
void app_main(void) {
// 创建LED任务,优先级为1
xTaskCreate(
led_task, // 任务函数
"LED_Task", // 任务名称
2048, // 栈大小
NULL, // 参数
1, // 优先级
NULL // 任务句柄
);
// 创建传感器任务,优先级为2(更高)
xTaskCreate(
sensor_task,
"Sensor_Task",
2048,
NULL,
2,
NULL
);
ESP_LOGI(TAG, "Tasks created successfully");
}
2. 队列通信示例
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_log.h"
static const char *TAG = "QUEUE_DEMO";
QueueHandle_t data_queue;
typedef struct {
int sensor_id;
float value;
uint32_t timestamp;
} sensor_data_t;
// 生产者任务:模拟传感器数据
void producer_task(void *parameter) {
sensor_data_t data;
int counter = 0;
while (1) {
// 生成模拟数据
data.sensor_id = counter % 3; // 0, 1, 2
data.value = 20.0 + (counter % 20);
data.timestamp = xTaskGetTickCount();
// 发 送数据到队列
if (xQueueSend(data_queue, &data, pdMS_TO_TICKS(100)) == pdTRUE) {
ESP_LOGI(TAG, "Sent: ID=%d, Value=%.1f", data.sensor_id, data.value);
} else {
ESP_LOGW(TAG, "Queue is full!");
}
counter++;
vTaskDelay(pdMS_TO_TICKS(1500));
}
}
// 消费者任务:处理传感器数据
void consumer_task(void *parameter) {
sensor_data_t received_data;
while (1) {
// 从队列接收数据
if (xQueueReceive(data_queue, &received_data, pdMS_TO_TICKS(1000)) == pdTRUE) {
ESP_LOGI(TAG, "Received: Sensor %d = %.1f at tick %lu",
received_data.sensor_id,
received_data.value,
received_data.timestamp);
// 模拟数据处理
vTaskDelay(pdMS_TO_TICKS(500));
} else {
ESP_LOGW(TAG, "No data received within timeout");
}
}
}
void app_main(void) {
// 创建队列(最多5个元素)
data_queue = xQueueCreate(5, sizeof(sensor_data_t));
if (data_queue == NULL) {
ESP_LOGE(TAG, "Failed to create queue");
return;
}
// 创建生产者和消费者任务
xTaskCreate(producer_task, "Producer", 3072, NULL, 2, NULL);
xTaskCreate(consumer_task, "Consumer", 3072, NULL, 2, NULL);
ESP_LOGI(TAG, "Queue demo started");
}
3. 信号量同步示例
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_log.h"
static const char *TAG = "SEMAPHORE_DEMO";
SemaphoreHandle_t binary_semaphore;
SemaphoreHandle_t mutex;
int shared_resource = 0;
// 任务1:等待信号量
void waiting_task(void *parameter) {
while (1) {
ESP_LOGI(TAG, "Waiting for semaphore...");
// 等待信号量
if (xSemaphoreTake(binary_semaphore, pdMS_TO_TICKS(5000)) == pdTRUE) {
ESP_LOGI(TAG, "Semaphore received! Processing...");
// 使用互斥锁保护共享资源
if (xSemaphoreTake(mutex, pdMS_TO_TICKS(1000)) == pdTRUE) {
shared_resource++;
ESP_LOGI(TAG, "Shared resource updated: %d", shared_resource);
xSemaphoreGive(mutex);
}
vTaskDelay(pdMS_TO_TICKS(1000));
} else {
ESP_LOGW(TAG, "Semaphore timeout!");
}
}
}
// 任务2:发送信号量
void signaling_task(void *parameter) {
while (1) {
vTaskDelay(pdMS_TO_TICKS(3000));
ESP_LOGI(TAG, "Giving semaphore...");
xSemaphoreGive(binary_semaphore);
// 同样访问共享资源
if (xSemaphoreTake(mutex, pdMS_TO_TICKS(1000)) == pdTRUE) {
ESP_LOGI(TAG, "Current shared resource: %d", shared_resource);
xSemaphoreGive(mutex);
}
}
}
void app_main(void) {
// 创建二进制信号量
binary_semaphore = xSemaphoreCreateBinary();
// 创建互斥锁
mutex = xSemaphoreCreateMutex();
if (binary_semaphore == NULL || mutex == NULL) {
ESP_LOGE(TAG, "Failed to create semaphores");
return;
}
// 创建任务
xTaskCreate(waiting_task, "Waiting_Task", 3072, NULL, 2, NULL);
xTaskCreate(signaling_task, "Signaling_Task", 3072, NULL, 2, NULL);
ESP_LOGI(TAG, "Semaphore demo started");
}
关键概念解释:
xTaskCreate():创建新任务vTaskDelay():任务延时,让出CPU给其他任务xQueueCreate()/xQueueSend()/xQueueReceive():队列操作xSemaphoreCreate.../xSemaphoreTake()/xSemaphoreGive():信号量操作- 优先级:数字越大优先级越高(0-24)
这些例子展示了ESP32 FreeRTOS的 核心功能,让你可以构建复杂的多任务应用程序。